﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using EnvRide.Core.ObjectModel;
using CodeMadeSimple.Common.Tests;
using System.Xml;
using CodeMadeSimple.PropertiesManagement;
using log4net.Core;

namespace EnvRide.Core.UnitTests
{
    [TestFixture]
    public class EnvRideProcessArgumentsTests : EnvRideBaseTest
    {
        [Test]
        public void HasErrors()
        {
            XmlDocument doc = new XmlDocument();

            EnvRideProcessArguments args = new EnvRideProcessArguments();

            Assert.IsFalse(args.HasErrors);

            args.HasErrors = true;

            Assert.IsTrue(args.HasErrors);

            args.HasErrors = false;

            Assert.IsFalse(args.HasErrors);
        }

        [Test]
        public void PropertyContext()
        {
            XmlDocument doc = new XmlDocument();

            EnvRideProcessArguments args = new EnvRideProcessArguments();

            PropertyContext propCtx = new PropertyContext();

            Assert.IsNull(args.PropertyContainer);

            args.PropertyContainer = propCtx;

            Assert.AreSame(propCtx, args.PropertyContainer);

            PropertyContext propCtx2 = new PropertyContext();

            args.PropertyContainer = propCtx2;

            Assert.AreSame(propCtx2, args.PropertyContainer);

            args.PropertyContainer = null;

            Assert.IsNull(args.PropertyContainer);
        }

        [Test]
        public void ParseValue()
        {
            EnvRideProcessArguments args = new EnvRideProcessArguments();

            AssertDoesNotContainsLoggedMessages(Level.Error);

            Assert.AreEqual("${Prop}", args.ParseValue("${Prop}"));

            AssertHasErrors(args, new[] { GetPropertyContainerNullMessage() });

            PropertyContext ctx = new PropertyContext("Ctx1");

            args.PropertyContainer = ctx;

            args.HasErrors = false;

            Appender.Clear();

            Assert.AreEqual("${Prop}", args.ParseValue("${Prop}"));

            AssertHasErrors(args, new[] { "Could not find any property with the locator \"Prop\"!" });

            ctx.AddProperty(new Property { Name = "Prop", Value = "Value" });
            ctx.AddProperty(new Property { Name = "Prop2", Value = "Value2" });

            args.HasErrors = false;

            Appender.Clear();
            
            Assert.AreEqual("Value", args.ParseValue("${Prop}"));

            AssertHasNoErrors(args);

            Assert.AreEqual("Value <- Value at the beggining!", args.ParseValue("${Prop} <- Value at the beggining!"));

            Assert.AreEqual("Property value here: Value in the middle!", args.ParseValue("Property value here: ${Prop} in the middle!"));

            Assert.AreEqual("Property value at the end: Value", args.ParseValue("Property value at the end: ${Prop}"));

            Assert.AreEqual("Property value almost at the end: Value ", args.ParseValue("Property value almost at the end: ${Prop} "));

            Assert.AreEqual(" Value <- Value2 -> Value ", args.ParseValue(" ${Prop} <- ${Prop2} -> ${Prop} "));

            PropertyContext relCtx = new PropertyContext("RelatedCtx");
            relCtx.AddProperty(new Property { Name = "Prop", Value = "RelatedValue" });

            ctx.AddRelationship("Rel", relCtx);

            args.PropertiesPrefix = ">Rel:";

            Assert.AreEqual("RelatedValue", args.ParseValue("${Prop}"));

            PropertyContext parentCtx = new PropertyContext("Parent");
            parentCtx.AddProperty(new Property { Name = "Prop", Value = "ParentValue" });

            parentCtx.AddChildContext(ctx);

            args.PropertiesPrefix = "^:";

            Assert.AreEqual("ParentValue", args.ParseValue("${Prop}"));
        }
    }
}
